#ifndef __WIZ_GEOMETRY_CIRCLE_HPP__SHANHAOBO_19800429__
#define __WIZ_GEOMETRY_CIRCLE_HPP__SHANHAOBO_19800429__

#include "../../WizAlgebra/Include/Linear/Vector3/WizAlgebraVector3.hpp"

#include "./WizGeometryEnums.hpp"

namespace Wiz
{
    namespace Circle
    {
        template<class ElementT>
        struct Type
        {
            typedef ElementT                            tElement;
            typedef ::Wiz::Vector2::Type<tElement>      tVector;
            typedef tVector                             tPosition;
            typedef const tPosition&                    tPositionIn;

            ::Wiz::Bool::Type Build(tPositionIn A, tPositionIn B, tPositionIn C)
            {
                tVector  e1 = C - B;
                tVector  e2 = A - C;
                tVector  e3 = B - A;
                tElement d1 = -(e2.Dot(e3));
                tElement d2 = -(e3.Dot(e1));
                tElement d3 = -(e1.Dot(e2));
                tElement c1 = d2 * d3;
                tElement c2 = d3 * d1;
                tElement c3 = d1 * d2;
                tElement c  = c1 + c2 + c3;
                if (::Wiz::IsZero(c))
                {
                    return ::Wiz::Bool::False;
                }

                m_Center = ((c2 + c3) * A + (c3 + c1) * B + (c1 + c2) * C) / (2 * c);

                m_RadiusSqr = (A.x - m_Center.x) * (A.x - m_Center.x) + (A.y - m_Center.y) * (A.y - m_Center.y);
                m_Radius    = ::Wiz::Sqrt(m_RadiusSqr);

                return ::Wiz::Bool::True;
            }

            ::Wiz::Bool::Type IsInclude(tPositionIn TestPnt) const
            {
                return ::Wiz::Less(m_Center.SqrDistance(TestPnt), m_RadiusSqr);
            }

            ::Wiz::Side::Type GetSide(tPositionIn TestPnt) const
            {
                const tElement DistanceSqr = m_Center.SqrDistance(TestPnt);

                if (::Wiz::IsEqual(DistanceSqr, m_RadiusSqr))
                {
                    return ::Wiz::Side::eOn;
                }

                return DistanceSqr < m_RadiusSqr ? ::Wiz::Side::eIn : ::Wiz::Side::eOut;
            }

            tPosition   m_Center;
            tElement    m_Radius;
            tElement    m_RadiusSqr;
        };
    } /// end of namespace Circle
} /// end of namespace Wiz

#endif /*__WIZ_GEOMETRY_CIRCLE_HPP__SHANHAOBO_19800429__*/
